#include "document.h"

#include <iostream>
#include <iomanip>
#include <typeinfo>

#include "data_io.h"

///body file for base class Document

Document::Document() throw()
{
}

Document::~Document() throw()
{
}

int Document::get_type() const throw()
{
	return(type);
}

int Document::get_issue_no() const throw()
{
	return(issue_no);
}

Date Document::get_date() const throw()
{
	return(date);
}

std::string Document::get_subject() const throw()
{
	return(subject);
}

std::string Document::get_partner() const throw()
{
	return(partner);
}

int Document::get_ref_no() const throw()
{
	return(ref_no);
}

std::string Document::document_type_name(const int p_type) throw()
{
	switch(p_type)
	{
		case ORDER:
		{
			return("Hatarozat");
			break;
		}
		case BILL:
		{
			return("Szamla");
			break;
		}
		case CLAIM:
		{
			return("Panaszos level");
			break;
		}
		case TENDER:
		{
			return("Ajanlatkero level");
			break;
		}
		default:
		{
			return("Ismeretlen tipus");
			break;
		}
	}
}

void Document::fill_in_document_data(std::istream &p_in_stream) throw(File_IO_exceptions, Document_exceptions, Date_exceptions)
{
	const bool p_from_std_cin=(typeid(p_in_stream)==typeid(std::cin));
	///different input procedure when reading from std::cin or from something else
	try
	{
		if(p_from_std_cin)
		{
			std::cout<<"Ugyszam    ? ";
		}
		this->set_issue_no(Data_IO::get_natural(p_in_stream));
		bool p_date_ok=true;
		do
		{
			if(p_from_std_cin)
			{
				std::cout<<"Kelt         "<<std::endl;
				std::cout<<"     ev    ? ";
			}
			int p_year;
			p_year=Data_IO::get_natural(p_in_stream);
			if(p_from_std_cin)
			{
				std::cout<<"     ho    ? ";
			}
			int p_month;
			p_month=Data_IO::get_natural(p_in_stream);
			if(p_from_std_cin)
			{
				std::cout<<"     nap   ? ";
			}
			int p_day;
			p_day=Data_IO::get_natural(p_in_stream);
			Date p_date(p_year,p_month,p_day);
			p_date_ok=p_date.is_valid_date();
			if(!p_date_ok)
			{
				if(p_from_std_cin)
				{
					///simply make user to give a correct value
					std::cerr<<" * Adjon meg egy ervenyes datumot: "<<std::endl;
				}
				else
				{
					///unable to make user to give a correct value
					File_IO_exceptions date_error("Hibas datum az adatfajlban (nem szamla).");
					std::cerr<<date_error.what()<<std::endl;
					throw date_error;
				}
			}
			else
			{
				this->set_date(p_date);
			}
		}while(!p_date_ok);
		if(p_from_std_cin)
		{
			std::cout<<"Targy      ? ";
		}
		this->set_subject(Data_IO::get_string(p_in_stream));
		if(p_from_std_cin)
		{
			std::cout<<"Partner    ? ";
		}
		this->set_partner(Data_IO::get_string(p_in_stream));
		if(p_from_std_cin)
		{
			std::cout<<"Iktatoszam ? ";
		}
		this->set_ref_no(Data_IO::get_natural(p_in_stream));
		if(p_from_std_cin)
		{
			///feedback for user
			std::cout<<std::endl;
			std::cout<<"A kovetkezo adatokat rogzitettuk:"<<std::endl;
			this->print_out_document_data(std::cout);
			std::cout<<std::endl<<"------------------------";
		}
	}
	catch(File_IO_exceptions e)
	{
		///read invalid value from file
		throw;
	}
	catch(...)
	{
		throw;
	}
}

int Document::print_out_document_data(std::ostream &p_out_stream) throw(Date_exceptions, Document_exceptions)
{
	try
	{
		const bool p_to_std_cout=(typeid(p_out_stream)==typeid(std::cout));
		///different output procedure when writing to std::cout or to something else
		if(p_to_std_cout)
		{
			std::cout<<std::endl<<"------------------------"<<std::endl;
			std::cout<<"Irat tipusa: ";
			std::cout<<Document::document_type_name(this->get_type())<<std::endl;;
			///prints type in human-readable format
		}
		else
		{
			p_out_stream<<this->get_type()<<std::endl;
		}
		if(p_to_std_cout)
		{
			std::cout<<"Ugyszam:   : ";
		}
		p_out_stream<<this->get_issue_no()<<std::endl;
		if(p_to_std_cout)
		{
			std::cout<<"Kelt       : ";
			p_out_stream<<this->get_date()<<std::endl;
			///date format is YYYY-MM-DD
		}
		else
		{
			p_out_stream<<this->get_date().get_year()<<std::endl;
			p_out_stream<<std::setfill('0')<<std::setw(2)<<this->get_date().get_month()<<std::endl;
			p_out_stream<<std::setfill('0')<<std::setw(2)<<this->get_date().get_day()<<std::endl;
			///date format is YYYY, MM and DD in induvidial lines
		}
		if(p_to_std_cout)
		{
			std::cout<<"Targy      : ";
		}
		p_out_stream<<this->get_subject()<<std::endl;
		if(p_to_std_cout)
		{
			std::cout<<"Partner    : ";
		}
		p_out_stream<<this->get_partner();
		if(p_to_std_cout)
		{
			if(0!=this->get_ref_no())
			{
				///no output
				std::cout<<std::endl<<"Iktatoszam : ";
				p_out_stream<<this->get_ref_no();
			}
		}
		else
		{
			p_out_stream<<std::endl<<this->get_ref_no();
		}
		return(0);
	}
	catch(...)
	{
		throw;
	}
}

void Document::set_issue_no(const int &p_issue_no) throw()
{
	this->issue_no=p_issue_no;
}

void Document::set_type(const int &p_type) throw()
{
	this->type=p_type;
}

void Document::set_date(const Date &p_date) throw()
{
	this->date=p_date;
}

void Document::set_ref_no(const int &p_ref_no) throw()
{
	this->ref_no=p_ref_no;
}

void Document::set_partner(const std::string &p_partner) throw()
{
	this->partner=p_partner;
}

void Document::set_subject(const std::string &p_subject) throw()
{
	this->subject=p_subject;
}
